home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / Tickle-4.0 (tcl) / tcl / expecTerm / expTerm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  21.4 KB  |  728 lines  |  [TEXT/MPS ]

  1. /* expTerm.c
  2. ***************************************************************************** 
  3. expecTerm version 1.0 beta
  4. Mark Weissman
  5. Christopher Matheus
  6. Copyright 1992 by GTE Laboratories Incorporated.
  7.  
  8. Portions of this work are in the public domain.  Permission to use,
  9. copy, modify, and distribute this software and its documentation for
  10. any purpose and without fee is hereby granted, provided that the above
  11. copyright notice appear in all copies and that both the copyright
  12. notice and warranty disclaimer appear in supporting documentation, and
  13. that the names of GTE Laboratories or any of their entities not be
  14. used in advertising or publicity pertaining to distribution of the
  15. software without specific, written prior permission.
  16.  
  17. GTE disclaims all warranties with regard to this software, including
  18. all implied warranties of merchantability and fitness for a particular
  19. purpose, even if GTE Laboratories Incorporated knows about the
  20. purpose.  In no event shall GTE be liable for any special, indirect or
  21. consequential damages or any damages whatsoever resulting from loss of
  22. use, data or profits, whether in an action of contract, negligence or
  23. other tortuous action, arising out of or in connection with the use or
  24. performance of this software.
  25.  
  26. This code is based on and may include parts of Don Libes' expect code:
  27.   expect written by: Don Libes, NIST, 2/6/90
  28.   Design and implementation of expect was paid for by U.S. tax
  29.   dollars.  Therefore it is public domain.  However, the author and NIST
  30.   would appreciate credit if this program or parts of it are used.
  31.  
  32. ******************************************************************************/
  33.  
  34. #include "win.h"
  35. #include "translate.h"
  36. #include "global.h"
  37. #include <errno.h>
  38.  
  39. /* #define USE_PAD */
  40. #ifdef USE_PAD
  41. #define NEWWIN(SROWS, SCOLS, PROWS, PCOLS) \
  42.   (struct _win_st *)newpad(PROWS,PCOLS)
  43. #define REFRESH(WIN, PMINROW, PMINCOL, SMINROW, SMINCOL, SMAXROW, SMAXCOL) \
  44.   prefresh(WIN, PMINROW, PMINCOL, SMINROW, SMINCOL, SMAXROW, SMAXCOL)
  45. #else
  46. #define NEWWIN(SROWS, SCOLS, PROWS, PCOLS) \
  47.   (struct _win_st *)newwin(SROWS,SCOLS,0,0)
  48. #define REFRESH(WIN, PMINROW, PMINCOL, SMINROW, SMINCOL, SMAXROW, SMAXCOL) \
  49.   wrefresh(WIN)
  50. #endif
  51.  
  52. long ChildDiedP=0;
  53. char Buffer[BUFSIZ];
  54. char *indent="";
  55. long InitScr = 0;
  56. /* #define DEBUG_EOF 1 */
  57. char in_curses = 0;
  58. static char was_in_curses_stack[64], *was_in_curses = was_in_curses_stack;
  59.  
  60. #define USE_SHELL_MODE
  61.  
  62. #ifdef USE_SHELL_MODE
  63. #define DefShellMode() def_shell_mode()
  64. #define DefProgMode()  def_prog_mode()
  65. #define ResetProgMode() reset_prog_mode()
  66. #define ResetShellMode() reset_shell_mode()
  67. #else
  68. static struct termios shell_termios, curses_termios;
  69. #define DefShellMode() tcgetattr(0,&shell_termios)
  70. #define DefProgMode()  tcgetattr(0,&curses_termios)
  71. #define ResetProgMode() tcsetattr(0,TCSANOW,&curses_termios)
  72. #define ResetShellMode() tcsetattr(0,TCSANOW,&shell_termios)
  73. #endif
  74.  
  75. PushCursesMode() {
  76.   *was_in_curses = in_curses;
  77.   if (!*was_in_curses) {
  78.     DefShellMode();
  79.     if (InitScr) {
  80.       ResetProgMode();
  81.     }
  82.     in_curses='c';
  83.   }
  84.   ++was_in_curses;
  85. }
  86.  
  87. PushShellMode () {
  88.   *was_in_curses = in_curses;
  89.   if (*was_in_curses) {
  90.     if (InitScr) {
  91.       DefProgMode();
  92.     }
  93.     ResetShellMode();
  94.     in_curses='\0';
  95.   }
  96.   ++was_in_curses;
  97. }
  98.  
  99. PopCursesMode() {
  100.   --was_in_curses;
  101.   if (!*was_in_curses) {
  102.     if (InitScr) {
  103.       DefProgMode();
  104.     }
  105.     ResetShellMode();
  106.     in_curses='\0';
  107.   }
  108. }
  109.  
  110. PopShellMode() {
  111.   --was_in_curses;
  112.   if (*was_in_curses) {
  113.     DefShellMode();
  114.     if (InitScr) {
  115.       ResetProgMode();
  116.     }
  117.     in_curses='y';
  118.   }
  119. }
  120.  
  121. #define WITH_CURSES(BODY) {\
  122.   PushCursesMode(); \
  123.   BODY; \
  124.   PopCursesMode(); \
  125. }
  126.  
  127. #define WITHOUT_CURSES(BODY) {\
  128.   PushShellMode(); \
  129.   BODY; \
  130.   PopShellMode(); \
  131. }
  132.  
  133. InitializeCurses() {
  134.   struct winsize ws;
  135.   ioctl(0, TIOCGWINSZ, &ws);
  136.   ioctl(0, TIOCSWINSZ, &ws);
  137.   WITH_CURSES({
  138.     if (!InitScr) {
  139.       initscr(); /* TermScreen = newterm("xterm",inp,outp); set_term(TermScreen); */
  140.       DefProgMode();
  141.       InitScr = 1;
  142.       scrollok(stdscr,FALSE);
  143.     }});
  144. }
  145.  
  146. #include <varargs.h>
  147. int
  148.   FuncallWithoutCurses(va_alist) 
  149. va_dcl
  150. {
  151.   va_list ap;
  152.   IFPTR func;
  153.   int result;
  154.   void *argv[16];
  155.   int argc, i;
  156.   char *fatalmess = NULL;
  157.   va_start(ap);
  158.   func = va_arg(ap, IFPTR);
  159.   argc = (int) va_arg(ap, int);
  160.   for (i=0; i< argc; ++i) argv[i] = (void *) va_arg(ap, void *);
  161.   va_end(ap);
  162.   WITHOUT_CURSES({
  163.     switch (argc) {
  164.     case 0:  result = (*func)(); break;
  165.     case 1:  result = (*func)(argv[0]); break;
  166.     case 2:  result = (*func)(argv[0], argv[1]); break;
  167.     case 3:  result = (*func)(argv[0], argv[1], argv[2]); break;
  168.     case 4:  result = (*func)(argv[0], argv[1], argv[2], argv[3]); break;
  169.     case 5:  result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4]); break;
  170.     case 6:  result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); break;
  171.     case 7:  result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); break;
  172.     case 8:  result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); break;
  173.     case 9:  result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]); break;
  174.     case 10: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); break;
  175.     case 11: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]); break;
  176.     case 12: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]); break;
  177.     case 13: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]); break;
  178.     case 14: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]); break;
  179.     case 15: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]); break;
  180.     case 16: result = (*func)(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15]); break;
  181.     default: fatalmess = "Illegal Number of args to FuncallWithoutCurses";
  182.     }});
  183.   if (fatalmess) { fatal(fatalmess); exit(-1); }
  184.   return(result);
  185. }
  186.  
  187. SESSION *Session, *CurrSession;
  188. SESSION *Sessions[WIN_SESSION_MAX];
  189. long MaxSession=0;
  190. long WinbarP=1;
  191. long Rows= 24;
  192. long Columns= 80;
  193.  
  194. ToggleWinbarP() { WinbarP = !WinbarP; }
  195.  
  196. SetCurrSession() {
  197.   CurrSession=Session;
  198. }
  199.  
  200. SetSessionFromFD(fd)
  201. int fd;
  202. {
  203.   Session = Sessions[fd];
  204.   return(Session?1:0);
  205. }
  206.  
  207. SessionBufferedInputP()
  208. {
  209.   return(Session && Session->input_cached_p);
  210. }
  211.  
  212. ResetWindow()
  213. {
  214.   WITH_CURSES({
  215.     clear();
  216.     if (loguser) refresh();
  217.     if (CurrSession) touchwin(CurrSession->win);
  218.     SetStatusLine(NULL);
  219.     winbar(1);});
  220. }
  221.  
  222. UpdateWindow(message) 
  223. char *message;
  224. {
  225.   SetStatusLine(message);
  226.   if (!SessionBufferedInputP()) WITH_CURSES(winbar((message && 1)));
  227. }
  228.  
  229. long CreateSession(num, Rows, Columns, MaxRow, MaxCol)
  230. int Rows, Columns, num, MaxRow, MaxCol;
  231. {
  232.   CurrSession = Session = Sessions[num] = (SESSION *)calloc(1,sizeof(SESSION));
  233.   Session->num = MaxSession;
  234.   ++MaxSession;
  235.   Session->rows = Rows; /* Should come from emulated lines */
  236.   Session->columns = Columns; /* Should come from emulated columns */
  237.   Session->lmarg = 0;
  238.   Session->rmarg = Session->columns;
  239.  
  240.   Session->pad.maxrow = (MaxRow > Rows) ? MaxRow : Rows;
  241.   Session->pad.minrow = Session->pad.mincol = 0L;
  242.   Session->pad.maxcol = Session->columns;
  243.  
  244.   Session->win = NEWWIN(Session->rows, Session->columns, Session->pad.maxrow,Session->pad.maxcol);
  245.  
  246.   Session->echop = atoi(get_var("term_echo")); /* CJM added get_var */
  247.   Session->crnlp = atoi(get_var("term_crnl")); /* CJM added get_var */
  248.   Session->breaksp = atoi(get_var("term_breaks")); /* MDW added get_var */
  249.   Session->tabspacep = atoi(get_var("term_tabspace")); /* CJM added get_var */
  250.   Session->rawBuff = (char *)malloc((Session->rawMax=WIN_RAW_MAX)+2);
  251.   Session->rawBuff[Session->rawIndex=0] = '\0';
  252.   Session->cookedIndex=0;
  253.   Session->term=NULL;
  254.   Session->expIndex = Session->rawEnd = Session->rawIndex = 0;
  255.   if (!Session->win) { fatal("window creation error"); exit(-1); }
  256.   scrollok(Session->win,FALSE);
  257.   /*  nodelay(stdscr,TRUE); noecho(); raw(); */
  258. }
  259.  
  260. DeleteSession() {
  261.   int i, s;
  262.   if (Session) {
  263.     Sessions[Session->fd] = NULL;
  264.     if (Session->raw_log) fclose(Session->raw_log);
  265.     Session->raw_log = NULL;
  266.     if (Session->cooked_log) fclose(Session->cooked_log);
  267.     Session->cooked_log = NULL;
  268.     delwin(Session->win);
  269.     if (Session->term) free(Session->term);
  270.     if (Session->rawBuff) free(Session->rawBuff);
  271.     if (Session == CurrSession) CurrSession = NULL;
  272.     fclose(Session->inp);
  273.     fclose(Session->outp);
  274.     free(Session);
  275.     Session = NULL;
  276.     --MaxSession;
  277.     for (s=0,i=0; i < MaxSession; ++s)
  278.       if (Sessions[s]) Sessions[s]->num = i++;
  279.   }
  280. }
  281.  
  282. fatal(message) 
  283. char *message;
  284. {
  285.   int n;
  286.  
  287.   while (MaxSession) {
  288.     for(n=0; n< WIN_SESSION_MAX; ++n) {
  289.       if (Session = Sessions[n]) {
  290.     DeleteSession();
  291.     break;
  292.       }
  293.     }
  294.   }
  295.   CurrSession=Session=NULL;
  296.   
  297.   if (InitScr) {
  298.     WITH_CURSES({
  299. /*      endwin(); */
  300.       InitScr = 0;
  301.     })}
  302.   if (message) fprintf(stderr,"%s\n",message);
  303.   if (message) exit(-1);
  304. }
  305.  
  306. SCREEN *TermScreen;
  307. EmulateTerminal(termtype, fd, rows, cols)
  308. int rows, cols;
  309. char *termtype;
  310. int fd;
  311. {
  312.   TermTab *term = NULL;
  313.   extern char *Strdup();
  314.   extern TermTab *EmulateTerm();
  315.   FILE *inp, *outp;
  316.   inp = fdopen(fd, "w");
  317.   if (!inp) return(0);
  318.   outp =  fdopen(fd, "r");
  319.   if (!outp) return(0);
  320.   if (termtype && (term = EmulateTerm(termtype, inp, outp))) {
  321.     InitializeCurses();
  322. /*    if (rows < term->int_lines) rows = term->int_lines; */
  323.     if (rows <= 0) rows = term->int_lines;
  324.     if (rows <= 0 || rows > (LINES - 1)) rows = (LINES - 1);
  325.     if (rows <= 0) rows = 24;
  326. /*    if (cols < term->int_cols) cols = term->int_cols; */
  327.     if (cols <= 0) cols = term->int_cols;
  328.     if (cols <= 0 || cols > COLS) cols = COLS;
  329.     if (cols <= 0) cols = 80;
  330.     { struct winsize ws;
  331.       ws.ws_row = rows; ws.ws_col = cols;
  332.       ws.ws_xpixel = ws.ws_ypixel = 0;
  333.       ioctl(fd, TIOCSWINSZ, &ws);
  334.     }
  335.     if (!SetSessionFromFD(fd)) {
  336.       WITH_CURSES({CreateSession(fd, rows, cols, term->int_lm, cols);});
  337.       Session->term = (TermTab *)malloc(sizeof(TermTab));
  338.     }
  339.     memcpy(Session->term, term, sizeof(TermTab));
  340.     Session->termOriginal = term;
  341.     if (Session->inp)  fclose(Session->inp);
  342.     if (Session->outp) fclose(Session->outp);
  343.     Session->fd = fd;
  344.     Session->inp = inp;
  345.     Session->outp = outp;
  346.     do_reset();
  347.   }
  348.   return(term?1:0);
  349. }
  350.     
  351. #define INPUT_UNREAD_BY_EXPECT -1
  352. #define INPUT_UNREAD_BY_TERM -2
  353. CheckInput(fd, t, any)
  354. int fd;
  355. double t;
  356. int any;
  357. {
  358.   fd_set rdrs;
  359.   struct timeval tv;
  360.   int result = 0;
  361.   
  362.   if (any && SetSessionFromFD(fd) && (Session->rawIndex < Session->rawEnd))
  363.     return(INPUT_UNREAD_BY_TERM);
  364.   DoubleToTimeval(t,&tv);
  365.   FD_ZERO(&rdrs);
  366.   FD_SET(fd,&rdrs);
  367.   if (SetAlarm(t+1.0)) {
  368.     result = -1;
  369.     result = select(1+fd,&rdrs,(fd_set *)0,(fd_set *)0,&tv);
  370.   }
  371.   ClearAlarm();
  372.   if (-1 == result && errno != EINTR) {
  373.     if (errno != EBADF) {
  374.       /* not prepared to handle anything else */
  375.       errorlog("select: %s\r\n",sys_errlist[errno]);
  376.       bye(-1);
  377.     }
  378.     debuglog("Select: Child Died");
  379.     fd_close(fd);
  380.     DeleteSession();
  381.     return(NULL);
  382.   }
  383.   if (result = FD_ISSET(fd, &rdrs)) return(result);
  384.   if (any && Session && (Session->expIndex < Session->rawEnd))
  385.     return(INPUT_UNREAD_BY_EXPECT);
  386.   else return(NULL);
  387. }
  388.  
  389. HandleSessionTerminal(buf, size, time_out)
  390. int size;
  391. double time_out;
  392. char *buf;
  393. {
  394.   long cc = 0 , iflag;
  395.   debuglog("EXPECTERM:HandleSessionTerminal(%x, %d, %f) [S->expIndex: %d, S->rawIndex %d, S->rawEnd %d, S->rawMax: %d]\r\n", 
  396.        buf, size, time_out,Session->expIndex,Session->rawIndex, Session->rawEnd, Session->rawMax);
  397.   iflag=CheckInput(Session->fd, time_out, TRUE);
  398.   if (iflag && iflag != INPUT_UNREAD_BY_EXPECT)
  399.     WITH_CURSES(handle_output());
  400.   cc = Session->rawEnd - Session->expIndex;
  401.   if (cc > size) cc = size;
  402.   if (cc > 0) memcpy(buf, (Session->rawBuff + Session->expIndex), cc);
  403.   Session->expIndex += cc;
  404.   if ((Session->rawIndex == Session->rawEnd) &&
  405.       (Session->expIndex == Session->rawEnd))
  406.     Session->rawIndex = Session->rawEnd = Session->expIndex = 0;
  407.   if (cc >= 0 && cc < size) buf[cc]='\0';
  408.   debuglog("EXPECTERM:=> %d, iflag: %d, [S->expIndex: %d, S->rawIndex: %d, S->rawEnd: %d, S->rawMax: %d]\r\n", 
  409.        cc, iflag, Session->expIndex,Session->rawIndex, Session->rawEnd, Session->rawMax);
  410.   return(cc);
  411. }
  412.  
  413. char UngetChar(c)
  414. char c;
  415. {
  416.   while(--Session->rawIndex && (Session->rawBuff[Session->rawIndex] != c));
  417.   return(c);
  418. }
  419.  
  420. double NextchInputWait = 0.0;
  421.  
  422. char Nextch(waitfor, cptr)
  423. char *cptr;
  424. double waitfor;
  425. {
  426.   char uchar = '\0';
  427.   register long index = Session->rawIndex, end = Session->rawEnd;
  428.   NextchInputWait = waitfor;
  429.   if (SessionBufferedInputP()) return('\0');
  430.   if (index >= end) {
  431.     while (end != -1) {
  432.       int n;
  433.       if (!CheckInput(Session->fd, 0.0, NULL)) {
  434.         if (waitfor == 0.0) break;
  435.         else {
  436.           extern double TimeOfDay();
  437.           double before, after;
  438.           before = TimeOfDay();
  439.           if (!CheckInput(Session->fd, waitfor, NULL)) { 
  440.             NextchInputWait = 0.0; 
  441.             break; 
  442.           }
  443.           after = TimeOfDay();
  444.           NextchInputWait -= (after - before);
  445.           if (NextchInputWait < 0.0) NextchInputWait = 0.0;
  446.           waitfor = 0.0;
  447.         }
  448.       }
  449.       if (end == Session->rawMax) {
  450.     Session->rawMax *= 2;
  451.     Session->rawBuff = (char *)realloc(Session->rawBuff, (Session->rawMax+16));
  452.       }
  453.       n = read(Session->fd, Session->rawBuff+end, Session->rawMax-end);
  454.       if (n <= 0) {
  455.     end = -1; index = 0; /* indicate failure */
  456.     break;
  457.       }
  458.       else {
  459.         register char *b    = (Session->rawBuff + end);
  460.         char *bmax = (Session->rawBuff + end + n);
  461.         while (b<bmax) { if (!(*b &= BITS7)) *b = NUL; ++b; }
  462.         if (Session->raw_log) write(fileno(Session->raw_log),(Session->rawBuff + end),n);
  463.         end += n;
  464.         Session->rawBuff[end]='\0';
  465.       }
  466.     }
  467.   }
  468.   if (index < end) {
  469.     uchar = Session->rawBuff[index++];
  470.     if (cptr) *cptr = uchar;
  471.   }
  472.   Session->rawIndex = index;
  473.   Session->rawEnd = end;
  474.   return(uchar);
  475. }
  476.  
  477. char charyx(y,x)
  478. long y,x;
  479. {
  480.   if (x>(Session->columns-1) || x < 0 || y>(Session->rows-1) || y < 0) return('\0');
  481.   return(Session->win->_y
  482.      ? (Session->win->_y[y][x]  & ~A_ATTRIBUTES)
  483.      : ' ');
  484. }
  485.  
  486. char attryx(y,x)
  487. long y,x;
  488. {
  489.   long attr;
  490.   if (x>(Session->columns-1) || x < 0 || y>(Session->rows-1) || y < 0) return('\0');
  491.   attr=(Session->win->_y)?(Session->win->_y[y][x] & A_ATTRIBUTES):0L;
  492.   if (!attr) return('N');
  493.   if (attr & A_PROTECT) return('P');
  494.   if (attr & A_INVIS) return('I');
  495.   if (attr & A_BOLD) return('B');
  496.   if (attr & A_STANDOUT) return('S');
  497.   if (attr & A_UNDERLINE) return('U');
  498.   if (attr & A_ALTCHARSET) return('A');
  499.   if (attr & A_REVERSE) return('R');
  500.   if (attr & A_DIM) return('D');
  501.   if (attr & A_BLINK) return('b');
  502.   return('?');
  503. }
  504.  
  505. BFLUSH(drain)
  506. int drain;
  507. {
  508.   if (Session->cooked_log) {
  509.     char string[XMAX], *s;
  510.     int x, y=Session->y, xmax = (drain ? Session->columns : Session->x);
  511.     for(s=string, x=Session->cookedIndex; x<xmax && (*s = charyx(y,x)); ++x, ++s);
  512.     if (drain) *s++ = '\n';
  513.     else Session->cookedIndex = x;
  514.     *s = 0;
  515.     fwrite(string,strlen(string),1,Session->cooked_log);
  516.     fflush(Session->cooked_log);
  517.   }
  518.   if (drain) Session->cookedIndex = 0;
  519. }
  520.  
  521. Go(ny,nx)
  522. long ny, nx;
  523. {
  524.   long dx;
  525.   if (Session->x >= Session->columns && ny == Session->y && (Session->term->bool_am==1)) {/* wraps right */
  526.     ++ny; nx=XMIN;
  527.   }
  528.   if (nx < 0 && (Session->term->bool_bw==1)) nx = Session->columns-nx; /* wrap left */
  529.   if (nx >= Session->columns) nx = Session->columns-1;
  530.   else if (nx < 0) nx = (Session->term->bool_bw==1) ? (Session->columns+nx) : 0;
  531.   if (ny < (Session->y) || (ny == (Session->y) && nx < (Session->x)) || 
  532.       ny < TMARG(Session) || ny > BMARG(Session))
  533.     CacheInput();
  534.   dx = (((Session->y)==ny) && ((Session->x) < nx)) ? (nx - (Session->x)) : 0;
  535. /*  while (dx-- > 0) BPUTC(Session,charyx((Session->y),(Session->x))); */
  536.   if (ny != (Session->y)) { Session->dribble_p=1; BFLUSH(1); }
  537.   else if (nx < (Session->x)) BFLUSH(1);
  538.   while (ny > BMARG(Session)) {
  539.     wmove(Session->win,TMARG(Session),0);
  540.     wdeleteln(Session->win);
  541.     wmove(Session->win,BMARG(Session),0);
  542.     winsertln(Session->win);
  543.     --ny;
  544.   }
  545.   while (ny < TMARG(Session)) {
  546.     wmove(Session->win,BMARG(Session),0);
  547.     wdeleteln(Session->win);
  548.     wmove(Session->win,TMARG(Session),0);
  549.     winsertln(Session->win);
  550.     ++ny;
  551.   }
  552.   wmove(Session->win,ny,nx);
  553.   getyx(Session->win,Session->y,Session->x);
  554. }
  555.  
  556. BPUTC(Session, c)
  557. SESSION *Session;
  558. char c;
  559. {
  560.   Session->input_p=TRUE;
  561.   Session->dribble_p=1;
  562.   if ((Session->x) >= (Session->columns) && (Session->term->bool_am==1)) /* wraps right */
  563.     Go(Session->y+1, XMIN);
  564.   if ((Session->x) >= Session->columns && (Session->term->bool_am!=1)) /* wraps right */
  565.     Go(Session->y, Session->columns-1);
  566.   if (Session->term->Local || !Session->term->InsertMode) {
  567.     int oattrs;
  568.     if (Session->term->Local) NextField(0);
  569.     else Break();
  570.     oattrs = Session->win->_attrs;
  571.     wattrset(Session->win, (Session->win->_y[Session->y][Session->x] & A_ATTRIBUTES));
  572.     waddch(Session->win,c);
  573.     wattrset(Session->win, oattrs);
  574.   }
  575.   else {
  576.     if (Session->win->_attrs & A_ALTCHARSET && Session->term->str_acsc > (char *)0) {
  577.       char *acsc = Session->term->str_acsc;
  578.       while (*acsc && *(++acsc) != c) ++acsc;
  579.       if (*acsc) c = *(acsc-1);
  580.     }
  581.     waddch(Session->win,c);
  582.   }
  583.   ++(Session->x);
  584. }
  585.  
  586. Write(fd, buf, siz)
  587. int fd;
  588. char *buf;
  589. unsigned siz;
  590. {
  591.   if (!SetSessionFromFD(fd)) return(write(fd, buf, siz));
  592.   if ((Session->term->Local == 1) || Session->echop) {
  593.     while (Session->rawEnd+siz >= Session->rawMax) {
  594.       Session->rawMax *= 2;
  595.       Session->rawBuff = (char *)realloc(Session->rawBuff, (Session->rawMax+16));
  596.     }
  597.     strncpy(Session->rawBuff+Session->rawEnd, buf, siz);
  598.     Session->rawEnd += siz;
  599.     WITH_CURSES(handle_output());
  600.     UpdateWindow(NULL);
  601.   }
  602.   if (Session->term->Local == 1)
  603.     return(siz);
  604.   else
  605.     return(write(fd, buf, siz));
  606. }
  607.  
  608. NextField(count)
  609. int count;
  610. {
  611.   int x=Session->x, y=Session->y, inc = ((count < 0) ? -1 : 1);
  612.   if (count < 0) count = -count;
  613.   if (Session->win->_y) {
  614.     do {
  615.       int saw00=0;
  616.       if (count)
  617.     while (attryx(y,x) == 'P') {
  618.       x+=inc;
  619.       if (x<0) {if (--y<0) y=Session->rows-1; x = Session->columns-1; break;}
  620.       else if (x >= Session->columns) {if(++y>=Session->rows) y=0; x=0;break;}
  621.     }
  622.       while (attryx(y,x) != 'P') {
  623.     if (!x && !y) if (++saw00 > 1) break;
  624.     x+=inc;
  625.     if (x<0) {if (--y<0) y=Session->rows-1; x = Session->columns-1;}
  626.     else if (x >= Session->columns) {if(++y>=Session->rows) y=0; x=0;}
  627.       }
  628.     } while(--count > 0);
  629.     Go(y, x);
  630.   }
  631. }
  632.  
  633. static char *StatusLine = NULL;
  634. int StatusLineIsDefaultP=TRUE;
  635.  
  636. char *SetStatusLine(statusline)
  637. char *statusline;
  638. {
  639.   static char buf[265];
  640.   extern int fd_max;
  641.   StatusLine = buf;
  642.   if (statusline == WIN_DEFAULT_WINBAR || 
  643.       (!statusline && StatusLineIsDefaultP)) {
  644.     StatusLineIsDefaultP=1;
  645.     if (!Session) {
  646.       sprintf(StatusLine,
  647.               "Flags: ????? Session:-1/0 Master:-1/%x x:-1/0 y:-1/0 *NONE*",
  648.               fd_max);
  649.     }
  650.     else if (Session == CurrSession)
  651.       sprintf(StatusLine,
  652.               "Flags: %c%c%c%c%c Session:%x/%x Master:%x/%x x:%02d/%2d y:%02d/%2d %s",
  653.               (Session->crnlp?'C':'c'),
  654.               (Session->echop?'E':'e'),
  655.               (Session->tabspacep?'T':'t'),
  656.               (Session->raw_log?'R':'r'),
  657.               (Session->cooked_log?'L':'l'),
  658.               Session->num,MaxSession-1,
  659.               Session->fd, fd_max,
  660.               Session->x, Session->columns-1,
  661.               Session->y, Session->rows-1,
  662.               Session->term->type);
  663.   }
  664.   else if (!statusline) return(NULL);
  665.   else if (statusline != WIN_DEFAULT_WINBAR) {
  666.     StatusLineIsDefaultP = 0;
  667.     strncpy(StatusLine,statusline,(COLS?COLS:80));
  668.   }
  669.   strcat(StatusLine,"                                                                               ");
  670.   StatusLine[(COLS?COLS:80)-1]='\0';
  671.   return(StatusLine);
  672. }
  673.  
  674. char *GetStatusLine() {
  675.   if (!StatusLine) SetStatusLine(WIN_DEFAULT_WINBAR);
  676.   return(StatusLine);
  677. }
  678.  
  679. long winbar(force)
  680. int force;
  681. {
  682.   static SESSION *osession=NULL;
  683.   static struct _win_st *wb=NULL;
  684.   long oy=0, ox=0;
  685.   extern loguser;
  686.   extern char in_curses;
  687.   int CurrP = (Session == CurrSession);
  688.   struct winsize ws;
  689.  
  690. /*  if (!InitScr) InitializeCurses(); */
  691.   if (!InitScr || !loguser) return(0);
  692.   if (!force && (!CurrSession || !CurrP)) return(0);
  693.  
  694.   if (!wb && WinbarP) {
  695.     int row = LINES, n;
  696.     if (row <= 0) row = 25;
  697.     wb = (struct _win_st *)newwin(0,0,row-1,0);
  698.     if (!wb) { 
  699.       struct _win_st *s = stdscr;
  700.       fatal("Could Not Create Winbar! Try bigger window."); 
  701.       exit(-1); 
  702.     }
  703.   }
  704.   if (wb) {
  705.     wstandout(wb);
  706.     mvwprintw(wb,0,0,"%s",StatusLine);
  707.     wstandend(wb);
  708.   }
  709.   if (Session != osession || force) {
  710.     if (Session) touchwin(Session->win); 
  711.     osession = Session; 
  712.   }
  713.   if (Session) {
  714.     getyx(Session->win,oy,ox);
  715.     wmove(Session->win,oy,ox);
  716.   }
  717.   if (WinbarP && wb && force) touchwin(wb);
  718.   if (WinbarP && wb && in_curses) wrefresh(wb);
  719.   if (in_curses && Session)
  720.     REFRESH(Session->win, 
  721.             Session->pad.minrow, Session->pad.mincol,
  722.             0, 0, Session->rows, Session->columns);
  723.   return(1);
  724. }
  725.  
  726.  
  727.  
  728.